﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Forest.Lion.Infrastructure.ModelHelper
{
    public static class ModelExtension
    {
        public static T CopyItem<T>(this T item) where T : class,new()
        {
            return CopyItem<T, T>(item);
        }

        public static TTo CopyItem<TFrom, TTo>(this TFrom from, Action<TFrom, TTo> action = null, params string[] copyNames)
            where TFrom : class,new()
            where TTo : class,new()
        {
            var fromType = typeof(TFrom);
            var toType = typeof(TTo);
            var properties = from fromProperty in fromType.GetProperties().Where(item => item.CanRead)
                             join toProperty in toType.GetProperties().Where(item => item.CanWrite)
                               on new { Name = fromProperty.Name, fromProperty.PropertyType }
                                equals new { Name = toProperty.Name, toProperty.PropertyType }
                             select
                             new
                             {
                                 fromProperty,
                                 toProperty,
                                 Name = fromProperty.Name
                             };

            if (copyNames.Length > 0)
            {
                properties = properties.Where(item => copyNames.Contains(item.Name));
            }

            var result = new TTo();
            foreach (var property in properties)
            {
                var value = property.fromProperty.GetValue(from, null);
                property.toProperty.SetValue(result, value, null);
            }
            if (action != null)
            {
                action(from, result);
            }
            return result;
        }

        public static List<TTo> DepthCopy<TFrom, TTo>(this IEnumerable<TFrom> collention,
            Action<TFrom, TTo> action = null, params string[] copyNames)
            where TFrom : class, new()
            where TTo : class, new()
        {
            var copyCollection = new List<TTo>();
            if (collention == null)
            {
                return copyCollection;
            }

            foreach (var fromEntity in collention)
            {
                copyCollection.Add(fromEntity.CopyItem<TFrom, TTo>(action, copyNames));
            }
            return copyCollection;
        }
    }
}
